unit windbase;

{$mode objfpc}{$H+}
{$ifndef NO_SMART_LINK}
{$smartlink on}
{$endif}
{.$PACKRECORDS C}
{$CALLING cdecl}
{$DEFINE EDB}



{.$DEFINE WINDBASE_OBSOLETE} //read NOTE #1 below
//
// Converted into Pascal unit by Artur R. Stuczynski <stootch.at.tlen.pl>
// March 9th, 2008
//
// Descriptions for structures come from the original windbase.h and
// windbase_edb.h
//
// ----------------------------------------------------------------------------
{
CONVERSION NOTES

NOTE #1
Bunch of functions are obsolete and should not be used, unless you need to
support a device with really old WinCE version. If this is your case,
enable WINDBASE_OBSOLETE definition at the beginning of this unit.
I moved the obsolete functions into windbase_obsolete.inc file and turning on
this symbol will cause the compiler to include them too.

NOTE #2
windbase.h and windbase_edb.h structures and routines are combined into one (this)
unit file.

NOTE #3
There are significant differences between CEDB and EDB, even if particular functions
are said to work with both database engines. Please read carefully documentation
provided on MSDN or in Windows Mobile SDK.
}


interface
uses windows;

const
  CoreDLL='coredll.dll';


{******************************************************************************}
{                    Constants                                                 }
{******************************************************************************}

const

{$IFNDEF WM_DBNOTIFICATION}
  WM_DBNOTIFICATION = $03FD;
{$ENDIF}

  CEDB_EXNOTIFICATION = $00000001;
  DB_CEOID_CREATED = WM_USER + $1;
  DB_CEOID_DATABASE_DELETED = WM_USER + $2;
  DB_CEOID_RECORD_DELETED = WM_USER + $3;
  DB_CEOID_FILE_DELETED = WM_USER + $4;
  DB_CEOID_DIRECTORY_DELETED = WM_USER + $5;
  DB_CEOID_CHANGED = WM_USER + $6;
  DB_NOTIFY_VOLUME_CHANGED = WM_USER + $8;
  DB_NOTIFY_RECORD_CREATED = DB_CEOID_CREATED;
  DB_NOTIFY_RECORD_CHANGED = DB_CEOID_CHANGED;
  DB_NOTIFY_RECORD_DELETED = DB_CEOID_RECORD_DELETED;
  REPL_CHANGE_WILL_CLEAR = $00000001;
  CEDB_SORT_DESCENDING = $00000001;
  CEDB_SORT_CASEINSENSITIVE = $00000002;
  CEDB_SORT_UNKNOWNFIRST = $00000004;
  CEDB_SORT_GENERICORDER = $00000008;  // internally used for generic ordering
  CEDB_SORT_IGNORENONSPACE = $00000010;
  CEDB_SORT_IGNORESYMBOLS = $00000020;
  CEDB_SORT_IGNOREKANATYPE = 00000040;
  CEDB_SORT_IGNOREWIDTH = $00000080;
  CEDB_SORT_STRINGSORT = $00000100;
  CEDB_SORT_UNIQUE = $00000200;
  CEDB_SORT_NONNULL = $00000400;
  CEDB_SORT_NO_POSITIONAL = $00000800;
  CEDB_SORT_PRIMARYKEY = (($00001000) OR CEDB_SORT_UNIQUE);

  {$IFNDEF EDB}
  CEDB_MAXSORTPROP = 3;
  {$ELSE EDB}
  CEDB_MAXSORTPROP = 16;
  {$ENDIF EDB}
  
  {$IFNDEF EDB}
  CEDB_SORTORDERSPECEX_VERSION = 1;
  {$ELSE EDB}
  CEDB_SORTORDERSPECEX_VERSION = 2;
  {$ENDIF EDB}
  
  ERROR_DBPROP_NOT_FOUND = ERROR_ACCESS_DENIED;
  ERROR_REPEATED_KEY = ERROR_ALREADY_EXISTS;

  {$IFNDEF EDB}
  MAXDBASENAMELEN = 32;
  {$ELSE EDB}
  MAXDBASENAMELEN = 128;
  {$ENDIF EDB}

  {$IFNDEF EDB}
  MAXSORTORDER = 4;
  {$ELSE EDB}
  MAXSORTORDER = 16;
  {$ENDIF EDB}

  CEDB_VALIDNAME = $0001;
  CEDB_VALIDTYPE = $0002;
  CEDB_VALIDSORTSPEC = $0004;
  CEDB_VALIDMODTIME = $0008;
  CEDB_VALIDDBFLAGS = $0010;
  CEDB_VALIDCREATE = (CEDB_VALIDNAME OR CEDB_VALIDTYPE OR
    CEDB_VALIDSORTSPEC OR CEDB_VALIDDBFLAGS);
  CEDB_NOCOMPRESS = $00010000;
  CEDB_SYSTEMDB = $00020000;

  {$IFNDEF EDB}
  BY_HANDLE_DB_INFORMATION_VERSION = 1;
  {$ELSE EDB}
  BY_HANDLE_DB_INFORMATION_VERSION = 2;
  {$ENDIF EDB}
  
  {$IFNDEF EDB}
  CEDBASEINFOEX_VERSION = 1;
  {$ELSE EDB}
  CEDBASEINFOEX_VERSION = 2;
  {$ENDIF EDB}

  CEDB_AUTOINCREMENT = $00000001;
  CEDB_SEEK_CEOID = $00000001;
  CEDB_SEEK_BEGINNING = $00000002;
  CEDB_SEEK_END = $00000004;
  CEDB_SEEK_CURRENT = $00000008;
  CEDB_SEEK_VALUESMALLER = $00000010;
  CEDB_SEEK_VALUEFIRSTEQUAL = $00000020;
  CEDB_SEEK_VALUEGREATER = $00000040;
  CEDB_SEEK_VALUENEXTEQUAL = $00000080;
  
  {$IFDEF EDB}
  CEDB_SEEK_PREFIX = $00000100;
  CEDB_SEEK_VALUEGREATEROREQUAL = $00000200;
  CEDB_SEEK_VALUESMALLEROREQUAL = $00000400;
  {$ENDIF EDB}

  CEVT_I2 = 2;
  CEVT_UI2 = 18;
  CEVT_I4 = 3;
  CEVT_UI4 = 19;
  CEVT_FILETIME = 64;
  CEVT_LPWSTR = 31;
  CEVT_BLOB = 65;
  CEVT_BOOL = 11;
  CEVT_R8 = 5;

  {$IFDEF EDB}
  CEVT_STREAM = 100;
  CEVT_RECID = 101;
  CEVT_AUTO_I4 = 102;
  CEVT_AUTO_I8 = 103;
  {$ENDIF EDB}

  CEDB_PROPNOTFOUND = $0100;
  CEDB_PROPDELETE = $0200;
  CEDB_MAXDATABLOCKSIZE = 4092;
  CEDB_MAXPROPDATASIZE = ((CEDB_MAXDATABLOCKSIZE*16)-1);
  CEDB_MAXRECORDSIZE = (128*1024);
  CEDB_MAXNUMRECORDS = $FFFF;
  CEDB_ALLOWREALLOC = $00000001;
  CEDB_NOBACKGROUNDFLUSH = $00010000;
  OBJTYPE_INVALID = 0;
  OBJTYPE_FILE = 1;
  OBJTYPE_DIRECTORY = 2;
  OBJTYPE_DATABASE = 3;
  OBJTYPE_RECORD = 4;
  OBJTYPE_EDB = 5;
  
  {$IFNDEF EDB}
  CEOIDINFOEX_VERSION = 1;
  {$ELSE EDB}
  CEOIDINFOEX_VERSION = 2;
  {$ENDIF EDB}

  EDB_MOUNT_FLAG = $80000000;
  DB_PROP_NOTNULL = $00000001;
  DB_PROP_COMPRESSED = $00000002;
  DBOPT_SESSION_MAX_CHANGES = $01;
  DBOPT_SESSION_LOCK_TIMEOUT = $02;
  DB_TRACK_INSERT = $00000001;
  DB_TRACK_UPDATE = $00000002;
  DB_TRACK_DELETE = $00000003;
  DB_TRACK_LEVEL = $0000007C;
  DB_TRACK_LEVEL_RECORD = $00000004;
  DB_TRACK_LEVEL_PROPINCLUSIVE = $00000008;
  DB_TRACK_LEVEL_PROPEXCLUSIVE = $00000010;
  DB_TRACK_LEVEL_PROPVALCHANGE = $00000020;
  DB_TRACK_ROWIDENTITY = $00000003;
  DB_TRACK_ROWIDENTITY_PK = $00000001;
  DB_SYNCSESSION_COMPLETE = $00000000;
  DB_SYNCSESSION_PARTIAL = $00000001;
  DB_SYNCSESSION_FAILED = $00000002;
  DB_SYNCSESSION_TRACKSERVER = $00000000;
  DB_SYNCSESSION_NOTRACK = $00000001;
  DB_SYNCSESSION_OVERRRIDELOCALCHANGES = $00000002;
  CEDBGEN_DEFAULT = $FFFFFFFFFFFFFFFF;
  CEDB_ISOLEVEL_DEFAULT = 1;
  CEDB_ISOLEVEL_READCOMMITTED = 1;
  CEDB_ISOLEVEL_REPEATABLEREAD = 2;
  CEDB_ISOLEVEL_SERIALIZABLE = 3;
  CEDB_ISOLEVEL_LAST = CEDB_ISOLEVEL_SERIALIZABLE;
  CEDB_CB_MIN_BUFFER_POOL = $00040000;
  CEDB_CB_MAX_BUFFER_POOL = $10000000;
  CEDB_AUTO_SHRINK_OFF = $0;
  CEDB_AUTO_SHRINK_THRESHOLD_MAX = 100;
  CEDB_FLUSH_INTERVAL_MIN = 1;
  CEDB_FLUSH_INTERVAL_MAX = 1000;
  CEDB_C_MIN_MAX_NOTIFY_CHANGES = 0;
  CEDB_C_MAX_MAX_NOTIFY_CHANGES = $FFFFFFFF;
  
  {$IFNDEF CCH_MAX_PASSWORD}
  {$DEFINE CCH_MAX_PASSWORD}
  CCH_MAX_PASSWORD = 40;
  {$ENDIF}

  CEVOLUMEOPTIONS_VERSION = 1;
  CEDB_BUFFERPOOL = $00000001;
  CEDB_AUTOSHRINKPERCENT = $00000002;
  CEDB_FLUSHINTERVAL = $00000004;
  CEDB_MAXNOTIFYCHANGES = $00000008;
  CEDB_DEFAULTTIMEOUT = $00000010;
  CEDB_PASSWORD = $00000020;
  CEPROPSPEC_VERSION = 1;

{******************************************************************************}
{                    Types/structures                                          }
{******************************************************************************}

type

  TCeOID = DWORD;
  PCeOID = ^TCeOID;
    
  TCeGuid = record
    Data1:DWORD;
    Data2:DWORD;
    Data3:DWORD;
    Data4:DWORD;
  end;
  
  PCeGuid = ^TCeGuid;

  TCeNotifyRequest = record
    dwSize: DWORD;
    hwnd: HWND;
    dwFlags: DWORD;
    hHeap: HANDLE;
    dwParam: DWORD;
  end;

  PCeNotifyRequest = ^TCeNotifyRequest;

  TCeNotification = record
    dwSize: DWORD;
    dwParam: DWORD;
    uType: UINT;
    guid: TCeGuid;
    oid: TCeOID;
    oidParent: TCeOID;
  end;
    
  PCeNotification = ^TCeNotification;

  TCeFileinfo = record
    dwAttributes: DWORD;
    oidParent: TCeOID;
    szFileName: array [0..MAX_PATH-1] of WChar;
    ftLastChanged: FILETIME;
    dwLength: DWORD;
  end;
      
  PCeFileinfo = ^TCeFileinfo;

  TCeDirInfo = record
    dwAttributes: DWORD;
    oidParent: TCeOID;
    szDirName: array [0..MAX_PATH-1] of WChar;
  end;
    
  PCeDirInfo = ^TCeDirInfo;
  
  TStoreInformation = record
    dwStoreSize: DWORD;
    dwFreeSize: DWORD;
  end;

  LPStoreInformation = ^TStoreInformation;

  TCePropID = DWORD;
  PCePropID = ^TCePropID;

  TCeRecordInfo = record
    oidParent: TCeOID;
  end;
  
  PCeRecordInfo = ^TCeRecordInfo;

  TSortOrderSpec = record
    propid: TCePropID;
    dwFlags: DWORD;
   end;
   
  PSortOrderSpec = ^TSortOrderSpec;

  TSortOrderSpecEx = record
    wVersion: WORD;
    wNumProps: WORD;
    wKeyFields: WORD;
    wReserved: WORD;
    rgPropID: array[0..CEDB_MAXSORTPROP-1] of TCePropID;
    rgdwFlags: array[0..CEDB_MAXSORTPROP-1] of DWORD;
  end;

  PSortOrderSpecEx = ^TSortOrderSpecEx;

  TCeDBaseInfo = record
    dwFlags: DWORD;
    szDbaseName: array[0..MAXDBASENAMELEN-1] of WChar;
    dwDbaseType: DWORD;
    wNumRecords: WORD;
    wNumSortOrder: WORD;
    dwSize: DWORD;
    ftLastModified: FILETIME;
    rgSortSpecs: array [0..MAXSORTORDER-1] of TSortOrderSpec;
  end;

  PCeDBaseInfo = ^TCeDBaseInfo;

  TCeDBaseInfoEx = record
    wVersion: WORD;
    wNumSortOrder: WORD;
    dwFlags: DWORD;
    szDatabaseName: array [0..MAXDBASENAMELEN-1] of WChar;
    dwDbaseType: DWORD;
    dwNumRecords: DWORD;
    dwSize: DWORD;
    ftLastModified: FILETIME;
    rgSortSpecs: array [0..MAXSORTORDER-1] of TSortOrderSpecEx;
  end;

  PCeDBaseInfoEx = ^TCeDBaseInfoEx;

  TByHandleDBInformation = record
    wVersion: WORD;
    wReserved: WORD;
    guidVol: TCeGuid;
    oidDbase: TCeOID;
    infDatabase: TCeDBaseInfoEx;
  end;

  LPByHandleDBInformation = ^TByHandleDBInformation;

  TCeBLOB = record
    dwCount: DWORD;
    lpb: LPBYTE;
  end;
  
  PCeBLOB = ^TCeBLOB;

  TCeValUnion = record
    case Word of
      0: (iVal: short);
      1: (uiVal: USHORT);
      2: (lVal: Long);
      3: (ulVal: ULONG);
      4: (filetime: FILETIME);
      5: (lpwstr: LPWSTR);
      6: (blob: TCeBLOB);
      7: (boolVal: BOOL);
      8: (dblValL: double);
  end;

  PCeValUnion = ^TCeValUnion;

  TCePropVal = record
    propid: TCePropID;
    wLenData: WORD;
    wFlags: WORD;
    val: TCeValUnion;
  end;

  PCePropVal = ^TCePropVal;
  
  TCeOIDInfo = record
    wObjType: WORD;
    wPad: Word;
    case WORD of
      0: (infFile: TCeFileInfo);
      1: (infDirectory: TCeDirInfo);
      2: (infDatabase: TCeDBaseInfo);
      3: (infRecord: TCeRecordInfo);
  end;
  
  PCeOIDInfo = ^TCeOIDInfo;
  
  TCeOIDInfoEx = record
    wVersion: WORD;
    wObjType: WORD;
    case Longint of
      0: (infFile: TCeFileInfo);
      1: (infDirectory: TCeDirInfo);
      2: (infDatabase: TCeDBaseInfoEx);
      3: (infRecord: TCeRecordInfo);
    end;

  PCeOIDInfoEx = ^TCeOIDInfoEx;

  TCeDBGen = ULONGLONG;
  
  TCeDBIsolationLevel = Integer;
  
  TCEVolumeOptions = record
    wVersion:WORD;
    cbBufferPool:DWORD;
    dwAutoShrinkPercent:DWORD;
    dwFlushInterval:DWORD;
    cMaxNotifyChanges:DWORD;
    dwDefaultTimeout:DWORD;
    wszPassword:array[0..CCH_MAX_PASSWORD-1] of WChar;
    dwFlags: DWORD;
  end;

  PCEVolumeOptions = ^TCEVolumeOptions;
  
  TCeChangeInfo = record
    dwChangeType: DWORD;
    stLastModified: SYSTEMTIME;
    genLastModified: TCeDBGen;
  end;

  PCeChangeInfo = ^TCeChangeInfo;
  
  TCePropSpec = record
    wVersion: WORD;
    propid: TCePropID;
    dwFlags: DWORD;
    pwszPropName: LPWSTR;
    cchPropName: DWORD;
  end;

  PCePropSpec = ^TCePropSpec;
{
 from Artur: the four following new types were introduced in order to support
 some of the fuctions. The trick is that instead feeding API with pointers to
 dynamic arrays we use addresses of THE FIRST ELEMENT in the array, i.e.
 @CEPROPSPECARR[0]
}
  TCePropIDArr = array of TCePropID;
  PCePropIDArr = ^TCePropIDArr;
  TCePropSpecArr = array of TCePropSpec;
  PCePropSpecArr = ^TCePropSpecArr;
  
{******************************************************************************}
{                    Macros->functions (see implementation section)            }
{******************************************************************************}

  function TypeFromPropID(propid: tCEPROPID): WORD;
  function CreateSystemGuid(pguid:PCeGuid): PCeGuid;
  function CreateInvalidGuid(pguid:PCeGuid): PCeGuid;
  {$IFDEF EDB}
  function CreateInvalidEDBGuid(pguid:PCeGuid):PCeGuid;
  {$ENDIF EDB}
  function CheckSystemGuid(pguid:PCeGuid): BOOL;
  function CheckInvalidGuid(pguid:PCeGuid): BOOL;

{******************************************************************************}
{                    DLL functions                                             }
{******************************************************************************}
type

  Tmemset = function(dest:pointer; c: Integer; count: size_t):pointer;
  Tmemcpy = function(dest:Pointer; const src:Pointer; count: size_t):Pointer;
  Twcslen = function(wchar_t:lpwstr):size_t;

  TGetStoreInformation = function(lpsi: LPStoreInformation): BOOL;
  
  TCeSetDatabaseInfoEx2 = function(pguid:PCeGuid; oidDbase:TCeOID;
    pNewInfo:PCeDBASEINFOEX):BOOL;
    
  TCeOpenDatabaseEx2 = function(pguid:PCeGuid; poid:PCeOID; lpszName:LPWSTR;
    pSort: PSORTORDERSPECEX; dwFlags:DWORD; pReq:PCeNOTIFYREQUEST):HANDLE;

  TCeDeleteDatabaseEx = function(pguid:PCeGuid; oid:TCeOID):BOOL;

  TCeGetDBInformationByHandle = function(hDbase: HANDLE;
    lpDBInfo: LPByHandleDBInformation): BOOL;

  TCeFindFirstDatabaseEx = function(pguid: PCeGuid; dwClassID: DWORD): HANDLE;

  TCeFindNextDatabaseEx = function(hEnum: HANDLE; pguid: PCeGuid): TCeOID;

  TCeCreateDatabaseEx2 = function(pguid: PCeGuid; pInfo: PCeDBASEINFOEX): TCeOID;

  TCeSeekDatabaseEx = function(hDatabase: HANDLE; dwSeekType: DWORD;
    dwValue: DWORD; wNumVals: WORD; lpdwIndex: LPDWORD): TCeOID;

  TCeDeleteRecord = function(hDatabase: HANDLE; oidRecord: TCeOID): BOOL;

  TCeReadRecordPropsEx = function(hDbase: HANDLE; dwFlags: DWORD;
    lpcPropID: LPWORD; rgPropID:PCePROPID; lplpBuffer: LPVoid;
    lpcbBuffer: LPDWORD; hHeap: HANDLE): TCeOID;

  TCeWriteRecordProps = function(hDbase: HANDLE; oidRecord: TCeOID; cPropID: WORD;
    rgPropVal: PCePROPVAL): TCeOID;

  TCeMountDBVol = function(pguid: PCeGuid; lpszVol: LPWSTR; dwFlags: DWORD): BOOL;

  TCeUnmountDBVol = function(pguid: PCeGuid): BOOL;

  TCeFlushDBVol = function(pguid: PCeGuid): BOOL;

  TCeEnumDBVolumes = function(pguid: PCeGuid; lpBuf: LPWSTR; dwSize: DWORD):BOOL;

  TCeFreeNotification = function(pRequest: PCeNOTIFYREQUEST;
    pNotify: PCeNOTIFICATION): BOOL;

  TCeChangeDatabaseLCID = procedure(pguid: PCeGuid; LCID: DWORD);

  TCeOidGetInfoEx2 = function(pguid: PCeGuid; oid: TCeOID;  oidInfo: PCeOIDInfoEx):BOOL;

  TCeCreateDatabaseWithProps = function(pGuid: PCeGuid; pInfo: PCeDBaseInfoEx;
    cProps: DWORD; prgProps: PCePropSpec): TCeOID;

  TCeGetDatabaseProps = function(hHandle: HANDLE; lpcPropID: LPWORD;
     prgPropID: PCePropIDArr; prgProps: Pointer): BOOL;
     
  TCeMountDBVolEx = function(pGuid: PCeGuid; pwszDBVol: LPWSTR;
    pOptions: PCeVolumeOptions; dwFlags: DWORD): BOOL;
    
  TCeOpenDatabaseInSession = function(hSession: HANDLE; pGuid: PCeGuid;
    poid: PCeOID; pwszName: LPWSTR; pSort: PSORTORDERSPECEX; dwFlags:DWORD;
    pRequest: PCeNOTIFYREQUEST):HANDLE;
     
{$IFDEF WINDBASE_OBSOLETE}
{$I windbase_obsolete.inc}
{$ENDIF WINDBASE_OBSOLETE}

//#pragma deprecated(CeCreateDatabase,CeCreateDatabaseEx,CeOpenDatabase,CeOpenDatabaseEx,CeOpenDatabaseEx2,CeMountDBVol)


  TCeAddDatabaseProps = function(pGuid: PCeGuid; oidDb: TCeOID; cProps: DWORD;
    prgProps: PCePropSpecArr): BOOL;

  TCeRemoveDatabaseProps = function(pGuid: PCeGuid; oidDb: TCeOID;
    cPropID: DWORD; prgPropID: PCePropIDArr): BOOL;

  TCeCreateSession = function(pGuid: PCeGuid): HANDLE;
  
  TCeGetDatabaseSession = function(hDatabase: Handle): Handle;
  
  TCeBeginTransaction = function(hSession: Handle; isoLevel: TCeDBIsolationLevel): BOOL;
  
  TCeEndTransaction = function(hSession: Handle; fCommit: BOOL): BOOL;
  
  // Session API's
{
  BOOL CeSetSessionOption(
      IN HANDLE hSession,
      IN ULONG ulOptionId,
      IN DWORD dwValue);


  BOOL CeEndTransaction(
      IN HANDLE hSession,
      IN BOOL fCommit);}

  // Stream API's

{  HANDLE CeOpenStream(
      IN HANDLE hDatabase,
      IN CEPROPID propid,
      IN DWORD dwMode);

  BOOL CeStreamRead(
      IN HANDLE hStream,
      OUT BYTE* prgbBuffer,
      IN DWORD cbRead,
      OUT DWORD* pcbRead);

  BOOL CeStreamWrite(
      IN HANDLE hStream,
      IN BYTE* prgbBuffer,
      IN DWORD cbWrite,
      OUT DWORD* pcbWritten);

  BOOL CeStreamSaveChanges(
      IN HANDLE hStream);

  BOOL CeStreamSeek(
      IN HANDLE hStream,
      IN DWORD cbMove,
      IN DWORD dwOrigin,
      OUT DWORD* pcbNewOffset);

  BOOL CeStreamSetSize(
      IN HANDLE hStream,
      IN DWORD cbSize);


  //-----------------------------------------------------------------------
  // Tracking functions
  //
  BOOL CeAddSyncPartner(
      IN  PCeGuid     pVolGuid,
      IN  PCeGuid     pSyncPartnerGuid,
      IN  LPCWSTR     pwszFriendlyName,
      IN  LPCWSTR     pwszFullName  );

  BOOL CeRemoveSyncPartner(
      IN  PCeGuid     pVolGuid,
      IN  PCeGuid     pSyncPartnerGuid );

  BOOL CeTrackDatabase(
      IN  PCeGuid     pVolGuid,
      IN  PCeGuid     pSyncPartnerGuid,
      IN  CEOID       oidDB,
      IN  DWORD       dwTrackingFlags );

  BOOL CeRemoveDatabaseTracking(
      IN  PCeGuid     pVolGuid,
      IN  PCeGuid     pSyncPartnerGuid,
      IN  CEOID       oidDB );

  BOOL CeTrackProperty(
      IN  PCeGuid     pVolGuid,
      IN  CEOID       oidDB,
      IN  CEPROPID    propid,
      IN  BOOL        fAddToScheme );

  BOOL CeBeginSyncSession(
      IN  HANDLE      hSession,
      IN  PCeGuid     pSyncPartnerGuid,
      IN  CEDBGEN     genFrom,
      IN  CEDBGEN     genTo,
      IN  DWORD       dwFlags,
      OUT CEDBGEN*    pGenCur );

  BOOL CeEndSyncSession(
      IN  HANDLE      hSession,
      IN  DWORD       dwOutcome );

  BOOL CeGetChangedRecordCnt(
      IN  HANDLE      hSession,
      IN  CEOID       oidDB,
      OUT DWORD*      pdwCnt );

  HANDLE CeGetChangedRecords(
      IN  HANDLE      hSession,
      IN  CEOID       oidDB,
      IN  DWORD       dwChangeType  );

  CEOID CeFindNextChangedRecord(
      IN  HANDLE      hChangeEnum );

  BOOL CeGetPropChangeInfo(
      IN  HANDLE          hChangeEnum,
      IN  CEOID           oidChangedRecord,
      IN  CEPROPID        propid,
      OUT BOOL*           pfPropChanged );

  BOOL CeGetRecordChangeInfo(
      IN  HANDLE           hChangeEnum,
      IN  CEOID            oidChangedRecord,
      OUT CECHANGEINFO* pInfo );

  BOOL CeMarkRecord(
      IN  HANDLE          hChangeEnum,
      IN  CEOID           oidChangedRecord,
      IN  BOOL            fChanged );

  BOOL CeAttachCustomTrackingData(
      IN  HANDLE          hDB,
      IN  CEOID           oidChangedRecord,
      IN  BYTE*           rgbData,
      IN  DWORD           ccb );

  BOOL CeGetCustomTrackingData(
      IN      HANDLE          hChangeEnum,
      IN      CEOID           oidChangedRecord,
      INOUT   BYTE*           rgbData,
      INOUT   DWORD*          pccb );

  BOOL CePurgeTrackingData(
      IN  PCeGuid     pVolGuid,
      IN  PCeGuid     pSyncPartnerGuid,
      IN  SYSTEMTIME* pstThreshold );

  BOOL CePurgeTrackingGenerations(
      IN  PCeGuid     pVolGuid,
      IN  PCeGuid     pSyncPartnerGuid,
      IN  CEDBGEN     genThreshold);
}





var
  GetStoreInformation: TGetStoreInformation = nil;
  CeMountDBVolEx: TCeMountDBVolEx = nil;
  CeUnmountDBVol: TCeUnmountDBVol = nil;
  CeFindFirstDatabaseEx: TCeFindFirstDatabaseEx = nil;
  CeFindNextDatabaseEx: TCeFindNextDatabaseEx = nil;
  CeSetDatabaseInfoEx2: TCeSetDatabaseInfoEx2 = nil;
  CeOpenDatabaseEx2: TCeOpenDatabaseEx2 = nil;
  CeDeleteDatabaseEx: TCeDeleteDatabaseEx = nil;
  CeGetDBInformationByHandle: TCeGetDBInformationByHandle = nil;
  CeCreateDatabaseEx2: TCeCreateDatabaseEx2 = nil;
  CeSeekDatabaseEx: TCeSeekDatabaseEx = nil;
  CeDeleteRecord: TCeDeleteRecord = nil;
  CeReadRecordPropsEx: TCeReadRecordPropsEx = nil;
  CeWriteRecordProps: TCeWriteRecordProps = nil;
  CeMountDBVol: TCeMountDBVol = nil;
  CeFlushDBVol: TCeFlushDBVol = nil;
  CeEnumDBVolumes: TCeEnumDBVolumes = nil;
  CeFreeNotification: TCeFreeNotification = nil;
  CeChangeDatabaseLCID: TCeChangeDatabaseLCID = nil;
  CeOidGetInfoEx2: TCeOidGetInfoEx2 = nil;
  CeCreateDatabaseWithProps: TCeCreateDatabaseWithProps = nil;
  CeGetDatabaseProps: TCeGetDatabaseProps = nil;
  CeOpenDatabaseInSession: TCeOpenDatabaseInSession = nil;
  CeAddDatabaseProps: TCeAddDatabaseProps = nil;
  CeRemoveDatabaseProps: TCeRemoveDatabaseProps = nil;
  CeCreateSession: TCeCreateSession = nil;
  CeGetDatabaseSession: TCeGetDatabaseSession = nil;
  CeBeginTransaction: TCeBeginTransaction = nil;
  CeEndTransaction: TCeEndTransaction = nil;
  
  memset: Tmemset;
  memcpy: Tmemcpy;
  wcslen: Twcslen;

implementation
uses dynlibs;

var LibH : dynlibs.TLibHandle;

function TypeFromPropID(propid: TCePropID): WORD;
begin
  Result := LoWord(propid);
end;

function CreateSystemGuid(pguid:PCeGuid): PCeGuid;
begin
  Result := memset(pguid, 0, SizeOf(TCeGuid));
end;

function CreateInvalidGuid(pguid:PCeGuid):PCeGuid;
begin
  if pguid=nil then
    New(pguid);
  Result := memset(pguid, -1, SizeOf(TCeGuid));
end;

{$IFDEF EDB}
function CreateInvalidEDBGuid(pguid:PCeGuid):PCeGuid;
begin
  Result := memset(pguid, 0, SizeOf(TCeGuid));
  (LPBYTE(pguid))^ := $ff;
end;
{$ENDIF EDB}

function CheckSystemGuid(pguid: PCeGuid): BOOL;
begin
  Result := BOOL(not((pguid^.Data1) or (pguid^.Data2) or (pguid^.Data3) or (pguid^.Data4)));
end;

function CheckInvalidGuid(pguid: PCeGuid): BOOL;
begin
  Result := BOOL(not(not((pguid^.Data1) and (pguid^.Data2) and (pguid^.Data3) and (pguid^.Data4))));
end;

initialization

  LibH := dynlibs.LoadLibrary(CoreDLL);
  if LibH <> NilHandle then
  begin
    Unaligned(Pointer(GetStoreInformation)) := GetProcAddress(LibH, 'GetStoreInformation');
    Unaligned(Pointer(CeMountDBVolEx)) := GetProcAddress(LibH, 'CeMountDBVolEx');
    Unaligned(Pointer(CeUnmountDBVol)) := GetProcAddress(LibH, 'CeUnmountDBVol');
    Unaligned(Pointer(CeFindFirstDatabaseEx)) := GetProcAddress(LibH, 'CeFindFirstDatabaseEx');
    Unaligned(Pointer(CeFindNextDatabaseEx)) := GetProcAddress(LibH, 'CeFindNextDatabaseEx');
    Unaligned(Pointer(CeSetDatabaseInfoEx2)) := GetPRocAddress(LibH, 'CeSetDatabaseInfoEx2');
    Unaligned(Pointer(CeOpenDatabaseEx2)) := GetProcAddress(LibH, 'CeOpenDatabaseEx2');
    Unaligned(Pointer(CeDeleteDatabaseEx)) := GetProcAddress(LibH, 'CeDeleteDatabaseEx');
    Unaligned(Pointer(CeGetDBInformationByHandle)) := GetProcAddress(LibH, 'CeGetDBInformationByHandle');
    Unaligned(Pointer(CeCreateDatabaseEx2)) := GetProcAddress(LibH, 'CeCreateDatabaseEx2');
    Unaligned(Pointer(CeSeekDatabaseEx)) := GetProcAddress(LibH, 'CeSeekDatabaseEx');
    Unaligned(Pointer(CeDeleteRecord)) := GetProcAddress(LibH, 'CeDeleteRecord');
    Unaligned(Pointer(CeReadRecordPropsEx)) := GetProcAddress(LibH, 'CeReadRecordPropsEx');
    Unaligned(Pointer(CeWriteRecordProps)) := GetProcAddress(LibH, 'CeWriteRecordProps');
    Unaligned(Pointer(CeMountDBVol)) := GetProcAddress(LibH, 'CeMountDBVol');
    Unaligned(Pointer(CeFlushDBVol)) := GetProcAddress(LibH, 'CeFlushDBVol');
    Unaligned(Pointer(CeEnumDBVolumes)) := GetProcAddress(LibH, 'CeEnumDBVolumes');
    Unaligned(Pointer(CeFreeNotification)) := GetProcAddress(LibH, 'CeFreeNotification');
    Unaligned(Pointer(CeChangeDatabaseLCID)) := GetProcAddress(LibH, 'CeChangeDatabaseLCID');
    Unaligned(Pointer(CeOidGetInfoEx2)) := GetProcAddress(LibH, 'CeOidGetInfoEx2');
    Unaligned(Pointer(CeCreateDatabaseWithProps)) := GetProcAddress(LibH, 'CeCreateDatabaseWithProps');
    Unaligned(Pointer(CeGetDatabaseProps)) := GetProcAddress(LibH, 'CeGetDatabaseProps');
    Unaligned(Pointer(CeOpenDatabaseInSession)) := GetProcAddress(LibH, 'CeOpenDatabaseInSession');
    Unaligned(Pointer(CeAddDatabaseProps)) := GetProcAddress(LibH, 'CeAddDatabaseProps');
    Unaligned(Pointer(CeRemoveDatabaseProps)) := GetProcAddress(LibH, 'CeRemoveDatabaseProps');
    Unaligned(Pointer(CeCreateSession)) := GetProcAddress(LibH, 'CeCreateSession');
    Unaligned(Pointer(CeGetDatabaseSession)) := GetProcAddress(LibH, 'CeGetDatabaseSession');
    Unaligned(Pointer(CeBeginTransaction)) := GetProcAddress(LibH, 'CeBeginTransaction');
    Unaligned(Pointer(CeEndTransaction)) := GetProcAddress(LibH, 'CeEndTransaction');
//    Pointer() := GetProcAddress(LibH, '');
//    Pointer() := GetProcAddress(LibH, '');
//    Pointer() := GetProcAddress(LibH, '');
//    Pointer() := GetProcAddress(LibH, '');
//    Pointer() := GetProcAddress(LibH, '');
//    Pointer() := GetProcAddress(LibH, '');
    
    Unaligned(Pointer(memset)) := GetProcAddress(LibH, 'memset');
    Unaligned(Pointer(memcpy)) := GetProcAddress(LibH, 'memcpy');
    Unaligned(Pointer(wcslen)) := GetProcAddress(LibH, 'wcslen');
  end;


finalization

  dynlibs.FreeLibrary(LibH);

end.
